from testing.flow import TestFlow
from testing.scenario import Scenario
from google.appengine.ext import db
from app.helpers.queries import Query
from app.models.valuesets import ValueSet
from app.models.versions import Version
from app.models.tags import Tag
from app.models.fieldsets import FieldSet

tf = TestFlow('Query Scenario Testing')

@tf.start
def f(flow):
  """ Initializes the db with stuff """
  flow.scenario = s = Scenario()
  flow.interface = i = flow.scenario.get_interface()
  
  flow.a = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'a@domain.com'}),
    (s.tags_fieldset.key(),
      {'skills': 'typing, sleeping',
       'interests' : 'working, running'}),
    (s.cat_fieldset.key(),
      {'neighborhood' : 'Mission',
       'favorite_color' : 'yellow'}))
  
  flow.b = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'b@domain.com'}),
    (s.tags_fieldset.key(),
      {'skills': 'typing, sleeping',
       'interests' : 'working, running'}),
    (s.cat_fieldset.key(),
      {'neighborhood' : 'Haight',
       'favorite_color' : 'green'}))
  
  flow.c = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'c@domain.com'}),
    (s.tags_fieldset.key(),
      {'skills': 'typing, sleeping',
       'interests' : 'working, running'}),
    (s.cat_fieldset.key(),
      {'neighborhood' : 'Haight',
       'favorite_color' : 'yellow'}))
  
  flow.d = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'd@domain.com'}),
    (s.cat_fieldset.key(),
      {'neighborhood' : 'SoMa',
       'favorite_color' : 'green'}))
  
  flow.e = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'e@domain.com'}),
    (s.tags_fieldset.key(),
      {'skills': 'sleeping',
       'interests' : 'working, running'}))
  
  flow.f = i.insert_or_update_row(
    (s.primary_fieldset.key(),
      {'email' : 'f@domain.com'}),
    (s.tags_fieldset.key(),
      {'skills': 'not sleeping',
       'interests' : 'working, running'}))
  
  i.commit()
       
  flow.mission_tag = Tag.get_by_key_name(Tag.get_key_name(
    flow.scenario.cat_fieldset.key(), 'neighborhood', 'Mission'))
  flow.haight_tag = Tag.get_by_key_name(Tag.get_key_name(
    flow.scenario.cat_fieldset.key(), 'neighborhood', 'Haight'))
  
  flow.green_tag = Tag.get_by_key_name(Tag.get_key_name(
    flow.scenario.cat_fieldset.key(), 'favorite_color', 'green'))
  flow.yellow_tag = Tag.get_by_key_name(Tag.get_key_name(
    flow.scenario.cat_fieldset.key(), 'favorite_color', 'yellow'))
    
  flow.typing_tag = Tag.get_by_key_name(Tag.get_key_name(
    flow.scenario.tags_fieldset.key(), 'skills', 'typing'))

def query_cat(flow):
  """ Queries only the cat fieldset based on a single tag """
  i = flow.interface
  s = flow.scenario
  return [x[0] for x in
    i.query([flow.scenario.cat_fieldset.key()], [flow.haight_tag.key()],
      [flow.scenario.cat_fieldset.key()])]

@tf.checks(query_cat, tf)
def f(flow, ret):
  flow.check_equal(len(ret), 2)
  
  flow.check_equal(ret[0].neighborhood, 'Haight')
  flow.check_equal(ret[0].favorite_color, 'Green')
  
  flow.check_equal(ret[1].neighborhood, 'Haight')
  flow.check_equal(ret[1].favorite_color, 'Yellow')

def query_multiple_fieldsets(flow):
  """ Queries the primary and cat fieldset based on a single tag """
  i = flow.interface
  s = flow.scenario
  return [x for x in i.query(
    [flow.scenario.primary_fieldset.key(), flow.scenario.cat_fieldset.key()],
    [flow.haight_tag.key()],
    [flow.scenario.cat_fieldset.key()])]

@tf.checks(query_multiple_fieldsets, tf)
def f(flow, ret):
  flow.check_equal(len(ret), 2)
  
  flow.check_equal(ret[0][0].email, 'b@domain.com')
  flow.check_equal(ret[0][1].neighborhood, 'Haight')
  flow.check_equal(ret[0][1].favorite_color, 'Green')
  
  flow.check_equal(ret[1][0].email, 'c@domain.com')
  flow.check_equal(ret[1][1].neighborhood, 'Haight')
  flow.check_equal(ret[1][1].favorite_color, 'Yellow')

def query_on_multiple_conditions(flow):
  """ Queries the primary fieldset and cat fieldset on multiple tags """
  i = flow.interface
  s = flow.scenario
  return [x for x in i.query(
    [flow.scenario.primary_fieldset.key(), flow.scenario.cat_fieldset.key()],
    [flow.green_tag.key(), flow.haight_tag.key()],
    [flow.scenario.cat_fieldset.key()])]

@tf.checks(query_on_multiple_conditions, tf)
def f(flow, ret):
  flow.check_equal(len(ret), 1)
  
  flow.check_equal(ret[0][0].email, 'b@domain.com')
  flow.check_equal(ret[0][1].neighborhood, 'Haight')
  flow.check_equal(ret[0][1].favorite_color, 'Green')

def query_on_multiple_fieldsets(flow):
  """ Queries on multiple tags across different conditions """
  i = flow.interface
  s = flow.scenario
  return [x for x in i.query(
    [flow.scenario.primary_fieldset.key()],
    [flow.green_tag.key(), flow.typing_tag.key()],
    [flow.scenario.cat_fieldset.key(), flow.scenario.tags_fieldset.key()])]

@tf.checks(query_on_multiple_fieldsets, tf)
def f(flow, ret):
  flow.check_equal(len(ret), 1)
  flow.check_equal(ret[0][0].email, 'b@domain.com')
  flow.check_equal(len(ret[0]), 1)

def query_paging(flow):
  """ Query using small batch size -- makes sure it gets everything """
  i = flow.interface
  s = flow.scenario
  i.batch_size = 2
  return [x for x in i.query(
    [flow.scenario.primary_fieldset.key(), flow.scenario.tags_fieldset.key()],
    [flow.typing_tag.key()],
    [flow.scenario.tags_fieldset.key()])]

@tf.checks(query_paging, tf)
def f(flow, ret):
  flow.check_equal(len(ret), 3)
  
  for r in ret:
    flow.check_equal(len(r), 2)
    flow.check_in('typing', r[1].skills)

